import { useEffect, useState, useMemo } from "react";
import { screenEnum, screenMap, sizeEnum } from "@/enums/breakpointEnum";

interface CreateCallbackParams {
	screen: sizeEnum;
	width: number;
	realWidth: number;
	screenEnum: typeof screenEnum;
	screenMap: Map<sizeEnum, number>;
	sizeEnum: typeof sizeEnum;
}

// 全局状态存储
let globalScreen: sizeEnum = sizeEnum.XL;
let globalRealWidth: number = typeof window !== "undefined" ? window.innerWidth : 0;
const listeners = new Set<() => void>();
const callbackListeners = new Set<(params: CreateCallbackParams) => void>();

function updateBreakpointState() {
	const bodyWidth = document.body.clientWidth;
	const xs = screenMap.get(sizeEnum.XS)!;
	const sm = screenMap.get(sizeEnum.SM)!;
	const md = screenMap.get(sizeEnum.MD)!;
	const lg = screenMap.get(sizeEnum.LG)!;
	const xl = screenMap.get(sizeEnum.XL)!;

	// 计算当前屏幕尺寸
	if (bodyWidth < xs) {
		globalScreen = sizeEnum.XS;
	} else if (bodyWidth < sm) {
		globalScreen = sizeEnum.SM;
	} else if (bodyWidth < md) {
		globalScreen = sizeEnum.MD;
	} else if (bodyWidth < lg) {
		globalScreen = sizeEnum.LG;
	} else if (bodyWidth < xl) {
		globalScreen = sizeEnum.XL;
	} else {
		globalScreen = sizeEnum.XXL;
	}

	// 更新实时宽度
	globalRealWidth = window.innerWidth;

	// 通知所有组件更新
	listeners.forEach(listener => listener());

	// 执行所有回调
	const params: CreateCallbackParams = {
		screen: globalScreen,
		width: screenMap.get(globalScreen)!,
		realWidth: globalRealWidth,
		screenEnum,
		screenMap,
		sizeEnum
	};
	callbackListeners.forEach(cb => cb(params));
}

// 初始化窗口监听
if (typeof window !== "undefined") {
	window.addEventListener("resize", updateBreakpointState);
	// 初始化状态
	updateBreakpointState();
}

export function useBreakpoint() {
	const [screen, setScreen] = useState(globalScreen);
	const [realWidth, setRealWidth] = useState(globalRealWidth);

	useEffect(() => {
		const listener = () => {
			setScreen(globalScreen);
			setRealWidth(globalRealWidth);
		};
		listeners.add(listener);
		return () => {
			listeners.delete(listener);
		};
	}, []);

	const width = useMemo(() => screenMap.get(screen), [screen]);

	return {
		screenRef: screen,
		widthRef: width,
		realWidthRef: realWidth,
		screenEnum
	};
}

export function createBreakpointListen(fn?: (params: CreateCallbackParams) => void) {
	if (fn) {
		callbackListeners.add(fn);
		// 立即触发一次初始化回调
		fn({
			screen: globalScreen,
			width: screenMap.get(globalScreen)!,
			realWidth: globalRealWidth,
			screenEnum,
			screenMap,
			sizeEnum
		});
	}

	return () => {
		if (fn) {
			callbackListeners.delete(fn);
		}
	};
}
